{UTF-8}
Unit routine;
Interface
Type
        {указатель на стэк}
        arptr = ^artype;
        artype = array[0..999] of word; {под стек - 1000 слов}
        {указатель на описатель процесса}
        descptr = ^procdesc;
        {описатель процесса}
        procdesc = record
                        ssreg,			{указатель на сегмент стека}
                        spreg: word;    {указатель на вершину стека}
                end;
        {передача управления от процесса oldProc процессу newProc}
        Procedure Transfer(oldProc:descptr; newProc:descptr);  
        {процедура запрещает прерывания}
		Procedure disable_interrupt;
		{процедура разрешает прерывания}
        Procedure enable_interrupt;
		{функция проверяет, была ли нажата клавиша}
        function isEscape:boolean;
		{функция проверяет, была ли нажата клавиша, и если была,
		то возвращает её в key}
		function getKey(var key:char):boolean;
Implementation
Uses crt;
Procedure disable_interrupt; Assembler;
asm
                cli;
end;
Procedure enable_interrupt; Assembler;
asm
                sti;
end;
 
Procedure Transfer(oldProc:descptr; newProc:descptr);
        Assembler;
        Asm                    {компилятор после Call Transfer
                                                подставляет push bp; mov bp,sp}
                les di, oldProc;
                mov es:[di], ss;        {oldProc.ssreg:=ss}
                mov es:[di+2], sp;      {oldProc.spreg:=sp}
                les di, newProc;
                mov ss, es:[di];        {ss:=newProc.ssreg}
                mov sp, es:[di+2];      {sp:=newProc.spreg}
                pop bp      {выталкивание bp выводит стек на адрес возврата}
                sti;
                ret 8
                {затолкнули 8 байтов - 4 слова - значения oldproc и newproc}
end;    {Transfer}
function isEscape:boolean;
var c:char;
begin
  if (keypressed) then
        begin
           writeln('isEscape running, procedure 1');
           c := readkey;
           writeln(ord(c));
           if (ord(c) = 0) then
                begin
                 c:=readkey;
                 if (c = chr(27)) then
                   begin
                        isEscape :=true;
                   end
                else
                   begin
                        isEscape :=false;
                   end;
                end
            else
                begin
                   if(ord(c) = 27) then isEscape := true else
                   isEscape:=false;
                end;
        end
    else
        begin
           isEscape:=false;
        end;
end;
function getKey;
begin
  if (keypressed) then
        begin
           getKey:=true;
		   key := readkey;
           if (ord(key) = 0) then
                 key:=readkey;
        end
    else
        begin
           getKey:=false;
        end;	
end;
end.